package geppetto.main;

import geppetto.cat.corpus.BilingualCorpus;
import geppetto.phraseHMM.WordTrie;
import geppetto.phraseHMM.lexicalWeighting.AbstractLexicalWeightingCalculator;
import geppetto.phraseHMM.phraseExtraction.GeneralPhraseExtraction;
import geppetto.phraseHMM.phraseExtraction.extractedphrase.ExtractedPhrasePairDataManager;
import geppetto.phraseHMM.phraseExtraction.extractedphrase.data.AdaptationTypeCalc;
import geppetto.phraseHMM.phraseExtraction.extractedphrase.data.ExtractedSentenceDataCalc;
import geppetto.phraseHMM.phraseExtraction.extractedphrase.data.LexicalWeightDataCalc;
import geppetto.phraseHMM.phraseExtraction.extractedphrase.data.ReorderingDataCalc;
import geppetto.phraseHMM.phraseExtraction.extractedphrase.data.ReorderingGraphDataCalc;
import geppetto.phraseHMM.phraseExtraction.extractedphrase.data.ScoreDataCalc;
import geppetto.phraseHMM.phraseExtraction.extractedphrase.data.SubPathsDataCalc;
import geppetto.reordering.AbstractReorderingCalculator;

import java.io.File;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;

public class ExtractPhrases {
	
	public static void main(String[] args) throws Exception{
		ExtractionUtils.loadParameters(args);
		ExtractionUtils.initArguments();
		ExtractionUtils.printArguments();
		ExtractionUtils.loadCorpus();
		ExtractionUtils.buildAlignmentSet();
		ExtractionUtils.buildAdaptationInfo();
		
		List<Integer> sentences = new ArrayList<Integer>();
		BilingualCorpus corpus = ExtractionUtils.getBilingualCorpus();
		ControlPoints controlPoints = new ControlPoints(ExtractionUtils.alignments);		
		controlPoints.setPhraseScorer(ExtractionUtils.getScorer(ExtractionUtils.scorerType));
		controlPoints.setPhraseCandidateExtractor(ExtractionUtils.getPhrasePairCandidateExtractor(ExtractionUtils.phrasePairCandidateExtractorType));
		controlPoints.setPhraseAccepter(ExtractionUtils.getAccepter(ExtractionUtils.accepterType));
		controlPoints.setOutputWriter(ExtractionUtils.getOutputWriter(ExtractionUtils.outputType, sentences));
		controlPoints.setAlignmentInfoWriter(ExtractionUtils.getAlignmentWriters(ExtractionUtils.alignmentInformation));
		
		AbstractReorderingCalculator reorderingCalc = ExtractionUtils.getReorderingCalc(ExtractionUtils.reordCalcType);
		AbstractLexicalWeightingCalculator lexicalWeightCalc = ExtractionUtils.getLexicalWeightingCalc(ExtractionUtils.lexicalCalcType);
		ExtractionUtils.addPhrasesToWordTries(controlPoints);
		
		ExtractedPhrasePairDataManager.addData("reordering", new ReorderingDataCalc(reorderingCalc));
		ExtractedPhrasePairDataManager.addData("score", new ScoreDataCalc(controlPoints.getPhraseScorer()));
		ExtractedPhrasePairDataManager.addData("lexical_weight", new LexicalWeightDataCalc(lexicalWeightCalc));
		LexicalWeightDataCalc calc = new LexicalWeightDataCalc(lexicalWeightCalc);
		calc.setReverse(true);
		ExtractedPhrasePairDataManager.addData("lexical_weight_reverse", calc);
		if(ExtractionUtils.getAdaptationInfo() != null){
			ExtractedPhrasePairDataManager.addData("adaptation_type", new AdaptationTypeCalc(ExtractionUtils.getAdaptationInfo()));
		}
		//ExtractedPhrasePairDataManager.addData("sub_paths", new SubPathsDataCalc());
		//ExtractedPhrasePairDataManager.addData("reordering_graph", new ReorderingGraphDataCalc(ExtractionUtils.getWordTrieSource(), ExtractionUtils.getWordTrieTarget()));
		ExtractedPhrasePairDataManager.addData("extracted_sentence_counts", new ExtractedSentenceDataCalc());
		
		System.out.println("initializing output writer");
		controlPoints.getOutputWriter().initialize();
		System.out.println("extracting phrase pairs");
		GeneralPhraseExtraction.generateMosesExtractionFile(corpus, BilingualCorpus.TRAIN_CORPUS, controlPoints);
		ExtractionUtils.getWordTrieSource().writeToFile(new PrintStream(new File(ExtractionUtils.getWordTrieSourceFile()), ExtractionUtils.encoding));
		ExtractionUtils.getWordTrieTarget().writeToFile(new PrintStream(new File(ExtractionUtils.getWordTrieTargetFile()), ExtractionUtils.encoding));
		controlPoints.getOutputWriter().writeInfo("sourceTrieFile", ExtractionUtils.getWordTrieSourceFile());
		controlPoints.getOutputWriter().writeInfo("targetTrieFile", ExtractionUtils.getWordTrieTargetFile());
		controlPoints.getOutputWriter().close();
	}
}
